#!/bin/bash
#
#   xrkmonitor license 
#
#   Copyright (c) 2020 by rockdeng
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
#
#   字符云监控(xrkmonitor) 开源版 (c) 2021 by rockdeng
#   当前版本：v1.0
#   使用授权协议： apache license 2.0
#
#   开源版主页：http://open.xrkmonitor.com
#   云版本主页：http://xrkmonitor.com
#  
#
#   云版本为开源版提供永久免费告警通道支持，告警通道支持短信、邮件、
#   微信等多种方式，欢迎使用
#
#   监控插件 mysql_slave_check 功能:
#        mysql 主从同步监控，主从不同步时会记录错误日志并发送异常告警
#
#   插件开发人员：官方
#   插件开发人员云账号ID：1
#
#
#   在该文件实现插件逻辑，可使用以下监控系统提供的函数：
#       1. 使用 xrkmonitor_cfg(cfg_name) 函数 -- 获取配置项 cfg_name 的配置值
#       2. 使用 xrkmonitor_add_attr / xrkmonitor_set_attr 函数上报监控点数据
#       3. 使用 xrkmonitor_add_strattr / xrkmonitor_set_strattr 函数上报字符串监控点数据 
#       4. 使用 xrkmonitor_log 上报日志
#
#

MYSQL_CONTEXT="mysql "
MYSQL_USER=$(xrkmonitor_cfg "XRK_MYSQL_USER")
MYSQL_PASS=$(xrkmonitor_cfg "XRK_MYSQL_PASS")
if [ "$MYSQL_USER" != "null" -a  "$MYSQL_PASS" != "null" ]; then
    MYSQL_CONTEXT="mysql -u${MYSQL_USER} -p${MYSQL_PASS} "
fi

function restart_slave()
{
    echo "stop slave " | ${MYSQL_CONTEXT}
    echo "start slave " | ${MYSQL_CONTEXT}
    xrkmonitor_log error "mysql master/slave may sync failed, will restart slave !"       
    xrkmonitor_set_attr XRK_MYSQL_SLAVE_FAILED 1
    exit 1
}

echo "show slave status \G" | ${MYSQL_CONTEXT} > _slave_tmp
if [ $? -ne 0 ]; then
    xrkmonitor_log error "execute mysql query failed, please check account or mysql service !"
    xrkmonitor_set_attr XRK_MYSQL_SLAVE_FAILED 1
    exit 1
fi

db_name=`cat _slave_tmp |grep Replicate_Do_DB|awk '{print $2}'`
db_name_id=$(xrkmonitor_cfg "XRK_TAB_FLD_DB_NAME")

m_host=`cat _slave_tmp |grep Master_Host|awk '{print $2}'`
m_host_id=$(xrkmonitor_cfg "XRK_TAB_FLD_DB_HOST")

file_name=`cat _slave_tmp |grep Master_Log_File|grep -v Relay_Master_Log_File|awk '{print $2}'`
file_name_id=$(xrkmonitor_cfg "XRK_TAB_FLD_CUR_FILE")

io_pos=`cat _slave_tmp |grep Read_Master_Log_Pos|awk '{print $2}'`

exe_pos=`cat _slave_tmp |grep Exec_Master_Log_Pos|awk '{print $2}'`

io_run=`cat _slave_tmp |grep Slave_IO_Running|awk '{print $2}'`
io_run_id=$(xrkmonitor_cfg "XRK_TAB_FLD_CUR_IO_STAT")

sql_run=`cat _slave_tmp |grep Slave_SQL_Running|grep -v Slave_SQL_Running_State|awk '{print $2}'`
sql_run_id=$(xrkmonitor_cfg "XRK_TAB_FLD_SQL_STAT")

sync_stat=`cat _slave_tmp |grep Slave_SQL_Running_State|awk -F ":" ' {print $2}'`

# 可能含有特殊字符需要转码
sync_stat=${sync_stat//"$"/" "}
sync_stat=${sync_stat//"#"/" "}
sync_stat_id=$(xrkmonitor_cfg "XRK_TAB_DB_SYNC_STAT")

tab_str="${db_name_id}#${db_name}\$${m_host_id}#${m_host}\$${file_name_id}#${file_name}\$${io_run_id}"
if [ "${io_run}" != "Yes" ];then
    tab_str="${tab_str}#No(fail)"
else
    tab_str="${tab_str}#Yes"
fi

tab_str="${tab_str}\$${sql_run_id}"
if [ "${sql_run}" != "Yes" ]; then
    tab_str="${tab_str}#No(fail)"
else
    tab_str="${tab_str}#Yes"
fi
tab_str="${tab_str}\$${sync_stat_id}#${sync_stat}"

stat_id=`date +%s`
xrkmonitor_table_log "XRK_TAB_MYSQL_SLAVE_CHECK" 60 "$stat_id" "$tab_str"

if [ "${io_run}" != "Yes" -o "${sql_run}" != "Yes" ]; then
    restart_slave
fi

stat_str="${db_name}#${m_host}#${file_name}#${io_pos}#${exe_pos}#${sync_stat}"
if [ -f _last_slave_pos ]; then
    last_stat_str=`cat _last_slave_pos`
    if [ "$stat_str" == "$last_stat_str" ]; then
# 同步进度没有变化，可能是正常情况也可能是网络故障，生成一条警告日志，不报警不重启slave 
        xrkmonitor_log warn "mysql slave info not changed  as - database:${db_name}, log file:${file_name}, io pos:${io_pos}, exe pos:${exe_pos}"
        exit 1
    fi
fi
xrkmonitor_log debug "mysql slave info - database:${db_name}, log file:${file_name}, io pos:${io_pos}, exe pos:${exe_pos}"
echo $stat_str > _last_slave_pos

